package metamodel.misc;

import metamodel.ClassNode;
import metamodel.CollectionRef;
import metamodel.FlatProperty;
import metamodel.coreservices.DefaultStringMapper;
import metamodel.transformer.BottomUpTransformingTreeTraverser;
import metamodel.transformer.BottomUpTreeTransformer;
import metamodel.transformer.PropertyValue;
import org.apache.commons.collections15.CollectionUtils;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.lang.StringUtils;

import java.util.Collection;
import java.util.List;

/**
 * User: felix
 * Date: 13.06.2005
 */
public class JSONSerializer {


    public Object serialize(ClassNode meta, Object object){
        return new BottomUpTransformingTreeTraverser(meta, new JsonTreeTransformer()).transform(object);
    }

    private class JsonTreeTransformer implements BottomUpTreeTransformer {

        public Object mapObject(ClassNode nodeDescriptor, List<PropertyValue> mappedProperties, Object originalObject) {
            return "{"+
                StringUtils.join(
                        CollectionUtils.collect(mappedProperties,new Transformer<PropertyValue, String>() {
                                public String transform(PropertyValue value) {
                                    return value.getMeta().getName()+":"+value.getValue();
                                }}),
                        ", ")
            +"}";
        }

        public Object mapCollection(CollectionRef collection, Collection mappedElements, Collection originalCollection) {
            return "["+StringUtils.join(mappedElements.iterator(),", ")+"]";
        }

        public Object mapFlatProperty(FlatProperty property, Object value)
        {
            final String stringValue = new DefaultStringMapper().toString(property, value);
            return
                    property.getDescriptor().getPropertyType()==String.class? 
                    "\""+stringValue+"\""
                    :stringValue;
        }

    }
}